// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.android.apps.moderator;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class SubmissionListEntry extends ModeratorListEntry {

  protected static final String TAG = SubmissionListEntry.class.getName();

  private static int barWidth;
  
  private final VoteBar minusBar = new VoteBar();
  private final VoteBar plusBar = new VoteBar();
  private final int seriesId;
  private final int submissionId;
  private final int topicId;
  private JSONObject vote;

  public SubmissionListEntry(JSONObject submission, JSONObject vote, int topicId) {
    super(submission);
    this.vote = vote;
    this.topicId = topicId;

    try {
      JSONObject id = submission.getJSONObject("id");
      this.seriesId = id.getInt("seriesId");
      this.submissionId = id.getInt("submissionId");

      JSONObject counters = submission.getJSONObject("counters");
      int minusVotes = counters.getInt("minusVotes");
      int plusVotes = counters.getInt("plusVotes");
      int largerVoteCount = Math.max(plusVotes, minusVotes);
      plusBar.setScalingThreshold(largerVoteCount);
      minusBar.setScalingThreshold(largerVoteCount);
      minusBar.setVotes(minusVotes);
      plusBar.setVotes(plusVotes);
    } catch (JSONException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public void addContextItems(ContextMenu menu, final Activity activity) {
    menu.add(R.string.vote_positive).setOnMenuItemClickListener(new OnMenuItemClickListener() {
      public boolean onMenuItemClick(MenuItem item) {
        if (((ModeratorActivity)activity).ensureLogin()) {
          vote(activity, 1);
        }
        return false;
      }
    });

    menu.add(R.string.vote_negative).setOnMenuItemClickListener(new OnMenuItemClickListener() {
      public boolean onMenuItemClick(MenuItem item) {
        if (((ModeratorActivity)activity).ensureLogin()) {
          vote(activity, -1);
        }
        return false;
      }
    });
    super.addContextItems(menu, activity);
  }

  public void customizeView(final View view, final Activity activity) {
    try {
      final ImageView noIcon = (ImageView) view.findViewById(R.id.NoIcon);
      final ImageView yesIcon = (ImageView) view.findViewById(R.id.YesIcon);

      TextView textView = (TextView) view.findViewById(R.id.Text);
      textView.setText(new StringBuilder().append("\"")
          .append(jsonObject.getString("text")).append("\"").toString());
      JSONObject attribution = jsonObject.getJSONObject("attribution");
      TextView attributionTextView = (TextView) view.findViewById(R.id.Attribution);
      attributionTextView.setText(attribution.optString("displayName", "") + " "
          + attribution.optString("location", ""));

      ImageView noBarEmpty = (ImageView) view.findViewById(R.id.NoBarEmpty);
      ImageView noBarFull = (ImageView) view.findViewById(R.id.NoBarFull);

      LayoutParams layoutParams = noBarFull.getLayoutParams();

      if (barWidth == 0) {
        barWidth = layoutParams.width;
      }

      int minusWidth = (int) (barWidth * minusBar.getWidth());

      noBarEmpty.setLayoutParams(new LinearLayout.LayoutParams(barWidth - minusWidth,
          layoutParams.height));
      noBarFull.setLayoutParams(new LinearLayout.LayoutParams(minusWidth, layoutParams.height));

      noIcon.setImageResource(vote != null
          && "MINUS".equals(vote.getString("vote")) ? R.drawable.no2
          : R.drawable.no);

      OnClickListener noListener = new OnClickListener() {
        public void onClick(View v) {
          if (((ModeratorActivity)activity).ensureLogin()) {
            noIcon.setImageResource(R.drawable.no2);
            yesIcon.setImageResource(R.drawable.yes);
            vote(activity, -1);
          }
        }
      };

      noBarEmpty.setOnClickListener(noListener);
      noBarFull.setOnClickListener(noListener);
      view.findViewById(R.id.NoIcon).setOnClickListener(noListener);

      ImageView yesBarEmpty = (ImageView) view.findViewById(R.id.YesBarEmpty);
      ImageView yesBarFull = (ImageView) view.findViewById(R.id.YesBarFull);

      int positiveWidth = (int) (barWidth * plusBar.getWidth());

      yesBarEmpty.setLayoutParams(new LinearLayout.LayoutParams(barWidth - positiveWidth,
          layoutParams.height));
      yesBarFull.setLayoutParams(new LinearLayout.LayoutParams(positiveWidth, layoutParams.height));

      yesIcon.setImageResource(vote != null
          && "PLUS".equals(vote.getString("vote")) ? R.drawable.yes2
          : R.drawable.yes);

      OnClickListener yesListener = new OnClickListener() {
        public void onClick(View v) {
          if (((ModeratorActivity)activity).ensureLogin()) {
            noIcon.setImageResource(R.drawable.no);
            yesIcon.setImageResource(R.drawable.yes2);
            vote(activity, 1);
          }
        }
      };

      yesBarFull.setOnClickListener(yesListener);
      yesBarFull.setOnClickListener(yesListener);
      view.findViewById(R.id.YesIcon).setOnClickListener(yesListener);

    } catch (JSONException e) {
      e.printStackTrace();
    }
  }

  public int getLayoutId() {
    return R.layout.submission_entry;
  }

  int getMinusVotes() {
    return minusBar.getVotes();
  }

  int getPlusVotes() {
    return plusBar.getVotes();
  }

  @Override
  protected String getUriString() {
    String e = Integer.toString(seriesId, 16);
    return "http://www.google.com/moderator/#15/e=" + e + "&t=" + e + "."
        + Integer.toString(topicId, 16) + "&q=" + e + "." + Integer.toString(submissionId, 16);
  }

  /**
   * Set the max votes for the bars.
   */
  public void setMaxBarVotes(int votes) {
    votes = Math.max(votes, Math.max(getPlusVotes(), getMinusVotes()));
    plusBar.setMaxVotes(votes);
    minusBar.setMaxVotes(votes);
  }

  /**
   * Submit a vote to the API
   * @param activity The parent activity
   * @param score The vote itself, -1 or +1
   */
  private void vote(final Activity activity, final int score) {
    Toast.makeText(activity, activity.getResources().getString(R.string.vote_registered),
        ModeratorActivity.TOAST_DURATION).show();
    final ModeratorActivity baseActivity = (ModeratorActivity) activity;
    new Thread(new Runnable(){
      @Override
      public void run() {
        try {
          JSONObject newVote = new JSONObject("{'data':{'kind':'vote','vote':'"
              + (score == 1 ? "PLUS" : "MINUS") + "','id':{'seriesId':'" + seriesId
              + "','submissionId':'" + submissionId + "'}}}");
          vote = newVote.getJSONObject("data");
          baseActivity.putJsonData(ModeratorActivity.API_URL_BASE + "series/" + seriesId
              + "/submissions/" + submissionId + "/votes/@me", newVote);
        } catch (AccessException e) {
          Log.e(TAG, "An exception occurred", e);
          // TODO: report vote error to user
        } catch (JSONException e) {
          Log.e(TAG, "An exception occurred", e);
          // TODO: report vote error to user
        }    
      }}).start();
  }
}
